浅析 ES6 特性

ES6 语法解决了很多过往 JS 的一些痛点, 但是我们不能只是使用它们, 而是弄清楚他们为什么可以这么做.
这里列举一些我常用的 ES6 语法的命令详解.

##Let, Const 特点
很多人知道 let, const 是 ES6 中新增的命令, 用于声明变量的, 其中 let 是声明了块级作用域中的变量, 使用 let, 它
遇大括号就会将该变量锁定在该区域中, 如果在大括号中使用了 let 命令声明了变量, 即使这个变量是全局变量, 那么在
let 命令之前使用或修改这个变量的值都是不允许的, 因为 let 命令不存在变量提升, 并且绑定了该作用域, 只能在声明
之后使用它.
而对于 const 命令, 是用于声明一个常量的, 对于常量, 我们在初始化的时候就应当赋值, 之后进行修改将会报错, 但是
const 命令保持不变的其实是它指向的那个内存单元的值不变, 对于基本类型来说, 指向的内存单元就是他们的值, 所以声
名了基本类型的常量保持不变, 但是如果声明了对象等引用类型的常量是不一样的, 常量指向的内存单元指向的是引用类型
的地址, 而地址指向的数据类型可以改变, 也就是说 const 声明的引用类型保证地址不变, 而其中的数据结构是可以改变
的, 用 const 声明的对象可以修改属性.

##Class, extends, super
class, extends, super 是 ES6 中对象继承的语法糖, 消除了原型继承的混乱的 .prototype/ .pro 与构造器
constructor 指针, 用简洁的 class 声明与 extends 命令来实现继承.

###class 缺点
class 也有缺点, 比如 class 声明的类还是相当原型继承中的构造函数, 它只是一个语法糖, class Pro 其实就是相当
于 Pro.protoytpe.constructor, class 声明的类也没有办法声明类成员属性, 在 constructor 中使用 this 绑定的
属性都是在实例中的, 没有办法声明类共有的属性, 注意是属性不是方法, 如果想类的所有实例都有一个共同属性的话,
class 就只能通过比较不优雅的方式来声明, 在 constructor 中利用 Pro.prototype.name = ‘zhangxiang’; 这样声明.

###super
对于 super ,我们会在使用 class extends 实现继承的时候, 在 constructor 中使用 super 来继承父类的属性与方法.
在构造器中, 需要先调用 super 再使用 this 进行增强, 这是因为子类的实例构建是基于父类实例之上的, 先使用创建
父类实例, 再在子类构造器中进行增强.这个是和 ES5 中的组合继承中在子类构造函数中调用父类构造函数的道理是类似
的(Farther.call(this)), 只是在实现上有点不同.

##箭头函数如何绑定 this ?
箭头函数有很多特点, 但是我们最喜欢的应该是它可以默认绑定 this 对象的值, 但是为什么呢? 因为箭头函数根本没有
this 对象, 它在创建的时候, 在 [[ scope ]] 属性中绑定了上一层上下文变量对象, 而它本身没有 this 对象, 所以当我
们使用箭头函数的 this 值的时候, 其实是直接借用了函数声明绑定的上一层上下文的 this 对象.

##模板字符串
在 ES6 中有一个好用的特性就是模板字符串, 它利用反引号来声明一个字符串, 抛弃了以前 ES5 中使用字符串拼接的方
式, 并且可以在字符串中使用 ${} 这样的符号进行变量内嵌.十分高效:

1
2
let name = 'zhangxiang';
let string = `this is a string named ${name}`;